using DotNetNuke.Entities.Modules;
using DotNetNuke.Services.Exceptions;
using DotNetNuke.Services.Localization;
using System;
using System.IO;
using System.Linq;

namespace DotNetNuke.Modules.DNNWeather
{
    /// <summary>
    /// The Settings class manages Module Settings
    ///
    /// Typically your settings control would be used to manage settings for your module. There are
    /// two types of settings, ModuleSettings, and TabModuleSettings.
    ///
    /// ModuleSettings apply to all "copies" of a module on a site, no matter which page the module
    /// is on.
    ///
    /// TabModuleSettings apply only to the current module on the current page, if you copy that
    /// module to another page the settings are not transferred.
    ///
    /// If you happen to save both TabModuleSettings and ModuleSettings, TabModuleSettings overrides ModuleSettings.
    ///
    /// Below we have some examples of how to access these settings but you will need to uncomment
    /// to use.
    ///
    /// Because the control inherits from DNNWeatherSettingsBase you have access to any custom
    /// properties defined there, as well as properties from DNN such as PortalId, ModuleId, TabId,
    /// UserId and many more.
    /// </summary>
    public partial class Settings : DNNWeatherSettingsBase
    {
        /// <summary>
        /// The key_ city identifier
        /// </summary>
        public const string Key_CityId = "CityId";

        /// <summary>
        /// The key_ city name
        /// </summary>
        public const string Key_CityName = "CityName";

        /// <summary>
        /// The key_ alternative city name
        /// </summary>
        public const string Key_AlternativeCityName = "AlternativeCityName";

        /// <summary>
        /// The key_ template identifier
        /// </summary>
        public const string Key_TemplateId = "TemplateId";

        /// <summary>
        /// The key_ degrees units
        /// </summary>
        public const string Key_DegreesUnits = "DegreesUnits";

        /// <summary>
        /// The key_ template custom file
        /// </summary>
        public const string Key_TemplateCustomFile = "TemplateCustomFile";

        #region Base Method Implementations

        /// <summary>
        /// LoadSettings loads the settings from the Database and displays them
        /// </summary>
        public override void LoadSettings()
        {
            try
            {
                if (Page.IsPostBack == false)
                {
                    FillLanguage();
                    FillAvailableTemplates();

                    //Check for the city data
                    if (Settings.Contains(Key_CityId) && Settings.Contains(Key_CityName))
                    {
                        hd_cityId.Value = Settings[Key_CityId].ToString();
                        hd_cityName.Value = Settings[Key_CityName].ToString();
                        lbl_currentLocation.Text = Localization.GetString("CurrentLocationData", this.LocalResourceFile)
                            .Replace("[CITYNAME]", Settings[Key_CityName].ToString())
                            .Replace("[CITYID]", Settings[Key_CityId].ToString());
                    }
                    else
                    {
                        lbl_currentLocation.Text = Localization.GetString("NoCurrentLocationSet", this.LocalResourceFile);
                    }

                    //Check for the template data
                    if (Settings.Contains(Key_TemplateId))
                    {
                        rdb_locationTemplateCustom.Checked = rdb_locationTemplateDefault.Checked = false;

                        WeatherTemplate template;
                        if (Enum.TryParse<WeatherTemplate>(Settings[Key_TemplateId].ToString(), out template))
                        {
                            switch (template)
                            {
                                case WeatherTemplate.Custom:
                                    rdb_locationTemplateCustom.Checked = true;
                                    if (Settings.Contains(Key_TemplateCustomFile))
                                    {
                                        var item = drp_customTemplate.Items.FindByValue(Settings[Key_TemplateCustomFile].ToString());
                                        if (item != null)
                                            item.Selected = true;
                                    }
                                    break;

                                default:
                                    rdb_locationTemplateDefault.Checked = true;
                                    break;
                            }
                        }
                        else
                        {
                            rdb_locationTemplateCustom.Checked = true;
                        }
                    }
                    else
                    {
                        rdb_locationTemplateDefault.Checked = true;
                    }

                    //Additional options
                    if (Settings.Contains(Key_DegreesUnits))
                    {
                        DegreesUnits deegreesUnits = (DegreesUnits)Enum.Parse(typeof(DegreesUnits), Settings[Key_DegreesUnits].ToString());
                        rdb_degreesUnits.ClearSelection();
                        switch (deegreesUnits)
                        {
                            case DegreesUnits.f:
                                rdb_degreesUnits.SelectedValue = deegreesUnits.ToString();
                                break;

                            default:
                                rdb_degreesUnits.SelectedValue = DegreesUnits.c.ToString();
                                break;
                        }
                    }

                    //Additional options
                    if (Settings.Contains(Key_AlternativeCityName))
                    {
                        txt_alternativeName.Text = Settings[Key_AlternativeCityName].ToString();
                    }
                }
            }
            catch (Exception exc) //Module failed to load
            {
                Exceptions.ProcessModuleLoadException(this, exc);
            }
        }

        /// <summary>
        /// Gets the available templates and fills them into the respective control
        /// </summary>
        private void FillAvailableTemplates()
        {
            var files = Directory.GetFiles(Server.MapPath(ControlPath + @"\Files\Templates\Custom"), "*.htm")
                        .Select(Path.GetFileName);

            drp_customTemplate.DataSource = files;
            drp_customTemplate.DataBind();
        }

        /// <summary>
        /// UpdateSettings saves the modified settings to the Database
        /// </summary>
        public override void UpdateSettings()
        {
            try
            {
                ModuleController modules = new ModuleController();

                //module settings
                modules.UpdateModuleSetting(ModuleId, Key_CityId, hd_cityId.Value);
                modules.UpdateModuleSetting(ModuleId, Key_CityName, hd_cityName.Value);
                modules.UpdateModuleSetting(ModuleId, Key_AlternativeCityName, txt_alternativeName.Text.Trim());

                if (rdb_locationTemplateCustom.Checked)
                {
                    modules.UpdateModuleSetting(ModuleId, Key_TemplateId, WeatherTemplate.Custom.ToString());
                    modules.UpdateModuleSetting(ModuleId, Key_TemplateCustomFile, drp_customTemplate.SelectedValue);
                }
                else
                {
                    modules.UpdateModuleSetting(ModuleId, Key_TemplateId, WeatherTemplate.Default.ToString());
                    modules.UpdateModuleSetting(ModuleId, Key_TemplateCustomFile, string.Empty);
                }

                modules.UpdateModuleSetting(ModuleId, Key_DegreesUnits, rdb_degreesUnits.SelectedValue);
            }
            catch (Exception exc) //Module failed to load
            {
                Exceptions.ProcessModuleLoadException(this, exc);
            }
        }

        #endregion Base Method Implementations

        #region "Aux Functions"

        /// <summary>
        /// Fills language data into the respective controls
        /// </summary>
        private void FillLanguage()
        {
            rq_cityName.ErrorMessage = Localization.GetString("RequiredCityName", this.LocalResourceFile);
            rdb_degreesUnits.Items[0].Text = Localization.GetString("AdditionalSettingDegreesCelsius", this.LocalResourceFile);
            rdb_degreesUnits.Items[1].Text = Localization.GetString("AdditionalSettingDegreesFahrenheit", this.LocalResourceFile);
            rdb_degreesUnits.Items[0].Attributes.Add("title", Localization.GetString("AdditionalSettingDegreesCelsiusToolTip", this.LocalResourceFile));
            rdb_degreesUnits.Items[1].Attributes.Add("title", Localization.GetString("AdditionalSettingDegreesFahrenheitToolTip", this.LocalResourceFile));

            rdb_locationTemplateDefault.Text = Localization.GetString("LocationTemplateOptionDefault", this.LocalResourceFile);
            rdb_locationTemplateCustom.Text = Localization.GetString("LocationTemplateOptionCustomTemplate", this.LocalResourceFile);
            rdb_locationTemplateDefault.Attributes.Add("title", Localization.GetString("LocationTemplateOptionDefaultToolTip", this.LocalResourceFile));
            rdb_locationTemplateCustom.Attributes.Add("title", Localization.GetString("LocationTemplateOptionCustomTemplateToolTip", this.LocalResourceFile));
        }

        #endregion "Aux Functions"

        #region "Enums"

        /// <summary>
        /// The available weather templates
        /// </summary>
        public enum WeatherTemplate
        {
            /// <summary>
            /// The default
            /// </summary>
            Default = 1,

            /// <summary>
            /// The custom
            /// </summary>
            Custom = 2
        }

        /// <summary>
        /// The degrees
        /// </summary>
        public enum DegreesUnits
        {
            /// <summary>
            /// The celsius
            /// </summary>
            c, //Celsius

            /// <summary>
            /// The Fahrenheit
            /// </summary>
            f //Fahrenheit
        }

        #endregion "Enums"
    }
}